package temp1.actions;

import java.io.File;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.ImageTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.testing.ContributionInfo;

/**
 * Our sample action implements workbench action delegate.
 * The action proxy will be created by the workbench and
 * shown in the UI. When the user tries to use the action,
 * this delegate will be created and execution will be 
 * delegated to it.
 * @see IWorkbenchWindowActionDelegate
 */
public class SampleAction implements IWorkbenchWindowActionDelegate {
	private IWorkbenchWindow window;
	private Clipboard clipboard;
	
	
	public SampleAction() {
	}


	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`


	public Object execute(ExecutionEvent event) throws Exception {

		Display display = Display.getCurrent();
		Shell shell = display.getActiveShell();
		parseComposites(shell);
		return null;
	}

	private void parseComposites(Shell shell) {

		Control[] controls = shell.getChildren();
		exitloop:
			for(Control control : controls) {
				if(control instanceof Composite) {
					Composite composite = (Composite)control;
					if(findActivePartCompositeAndTakeSnapshot(composite)) {
						break exitloop;
					}
				}
			}
	}

	private boolean findActivePartCompositeAndTakeSnapshot(Composite composite) {

		boolean isSnapshot = false;
		if(checkNextComposite(composite)) {
			/*
			 * Find active composite in the sub composites of the given element.
			 */
			 Control[] controls = composite.getChildren();
			for(Control control : controls) {
				if(control instanceof Composite) {
					Composite nextComposite = (Composite)control;
					isSnapshot = findActivePartCompositeAndTakeSnapshot(nextComposite);
				}
			}
		} else {
			/*
			 * Copy the selected composite to clipboard.
			 */
			copyCompositeToClipboard(composite);
			isSnapshot = true;
		}
		return isSnapshot;
	}

	private boolean checkNextComposite(Composite composite) {

		boolean checkNextComposite = true;
		/*
		 * If the composite is focused or has focused sub elements, it's the one we'd like to have.
		 */
		Composite parent = composite.getParent();
		if(parent != null) {
			Object object = parent.getData();
			if(object instanceof ContributionInfo) {
				ContributionInfo contributionInfo = (ContributionInfo)object;
				if(viewOrEditorIsFocused(composite, contributionInfo)) {
					checkNextComposite = false;
				}
			}
		}
		return checkNextComposite;
	}

	private boolean viewOrEditorIsFocused(Composite composite, ContributionInfo contributionInfo) {

		boolean isFocused = false;
		String elementType = contributionInfo.getElementType();
		if(elementType.equals("view") || elementType.equals("editor")) {
			if(compositeOrSubcomponentIsFocused(composite)) {
				isFocused = true;
			}
		}
		return isFocused;
	}

	private boolean compositeOrSubcomponentIsFocused(Control control) {

		boolean isFocused = false;
		if(control.isFocusControl()) {
			isFocused = true;
		} else {
			if(control instanceof Composite) {
				/*
				 * Check each containing element
				 */
				Control[] controls = ((Composite)control).getChildren();
				exitloop:
					for(Control controlx : controls) {
						/*
						 * Is a sub control focused?
						 */
						if(compositeOrSubcomponentIsFocused(controlx)) {
							isFocused = true;
							break exitloop;
						}
					}
			}
		}
		return isFocused;
	}

	private void copyCompositeToClipboard(Composite composite) {

		String message;
		Image image = getImage(composite);
		if(image == null) {
			message = "The focus of the selected view/editor couldn't be retrieved.";
		} else {
			ImageTransfer imageTransfer = ImageTransfer.getInstance();
			Object[] data = new Object[]{image.getImageData()};
			Transfer[] dataTypes = new Transfer[]{imageTransfer};
			clipboard.setContents(data, dataTypes);
			message = "The selected view/editor has been copied to clipboard.";
		}
		openMessageBox(message);
	}

	private Image getImage(Composite composite) {

		GC gc = null;
		Image image = null;
		Display display = Display.getCurrent();
		try {
			gc = new GC(composite);
			image = new Image(display, composite.getBounds());
			gc.copyArea(image, 0, 0);
		} finally {
			if(gc != null) {
				gc.dispose();
			}
		}
		return image;
	}

	private void openMessageBox(String message) {

		Display display = Display.getCurrent();
		String text = "Copy Selection To Clipboard";
		Shell shell = display.getActiveShell();
		MessageBox messageBox = new MessageBox(shell, SWT.NONE);
		messageBox.setText(text);
		messageBox.setMessage(message);
		messageBox.open();
	}


















	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


	private int c = 0;

	public void run(IAction action) {
//		MessageDialog.openInformation(
//				window.getShell(),
//				"Temp1",
//				"Hello, Eclipse world");
		
		clipboard = new Clipboard(Display.getDefault());
		
		c++;
		
		String filePath = System.getProperty("user.home")+File.separator+"Desktop"+File.separator+"screen"+c+".png";
		
		
		GC gc = null;
		Image image = null;
		Display display = Display.getCurrent();
		Rectangle rect = display.getActiveShell().getClientArea();
		
		try {
			gc = new GC(display);
			image = new Image(display, rect);
			gc.copyArea(image, 0, 0);
		} finally {
			if(gc != null) {
				gc.dispose();
			}
		}
		
		ImageTransfer imageTransfer = ImageTransfer.getInstance();
		Object[] data = new Object[]{image.getImageData()};
		Transfer[] dataTypes = new Transfer[]{imageTransfer};
		clipboard.setContents(data, dataTypes);
		
		ImageLoader imageLoader = new ImageLoader();
        imageLoader.data = new ImageData[] { image.getImageData() };
        imageLoader.save(filePath, SWT.IMAGE_PNG);
		
		
		
		
		
		
		
		
		
		
		
		
		
//		try {
//			execute(null);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
		
	}

	/**
	 * Selection in the workbench has been changed. We 
	 * can change the state of the 'real' action here
	 * if we want, but this can only happen after 
	 * the delegate has been created.
	 * @see IWorkbenchWindowActionDelegate#selectionChanged
	 */
	public void selectionChanged(IAction action, ISelection selection) {
	}

	/**
	 * We can use this method to dispose of any system
	 * resources we previously allocated.
	 * @see IWorkbenchWindowActionDelegate#dispose
	 */
	public void dispose() {
	}

	/**
	 * We will cache window object in order to
	 * be able to provide parent shell for the message dialog.
	 * @see IWorkbenchWindowActionDelegate#init
	 */
	public void init(IWorkbenchWindow window) {
		this.window = window;
	}
}